
#include <BVectorArray>
#include <BCoordArray>
#include "member_BGeoSphere.h"

using namespace BWE;

member_BGeoSphere::member_BGeoSphere(BGeoSphere* geosphere)
{
	boss = geosphere;
	radius = 0;
	segments = 0;
	rebuild();
}
member_BGeoSphere::~member_BGeoSphere()
{

}

int member_BGeoSphere::pointCount(int level)
{
	int half = segments / 2;
	int count = (half - abs(level - half)) * 5;
	return count;
}

bool member_BGeoSphere::rebuild()
{
	BVectorArray* vertices = new BVectorArray();
	BVectorArray* normals = new BVectorArray();
	BCoordArray* coords = new BCoordArray();
	BColorArray* colors = new BColorArray();

	int times = 0;
	float angleStepV = (float)(PI / segments);
	for (int r = 1; r < segments; r++)
	{
		float angleV = angleStepV * r;

		float nz = cos(angleV);
		float lr = sin(angleV);
		BColor color(1, 1, 0);
		if (times % 2)
			color = BColor(0, 255, 0);
		if (r == segments / 2)
			color = BColor(0, 255, 255);
		times++;
		float circleRadius = sin(angleV) * radius;
		int count = pointCount(r);
		static BVector buffer[10000];
		float rstep = PI2 / count;
		float ty = 1.0f / segments * r;
		float txs = 1.0f / count;
		for (int i = 0; i < count; i++)
		{
			float angleH = rstep * i;
			float nx = cos(angleH) * lr;
			float ny = sin(angleH) * lr;
			BVector normal(nx, ny, nz);
			normals->append(normal);
			coords->append(BCoord(txs * i, ty));
			buffer[i] = normal * radius;
			if (i == 0)
				colors->append(BColor(255, 0, 255));
			else if (0 == (i % (count / 5)))
				colors->append(BColor(0, 255, 255));
			else
				colors->append(color);
		}
		vertices->append(buffer, count);
	}
	vertices->append(BVector(0, 0, radius));
	coords->append(BCoord(0.5f, 0));
	colors->append(BColor(255, 0, 255));

	vertices->append(BVector(0, 0, -radius));
	coords->append(BCoord(0.5f, 1.0f));
	colors->append(BColor(255, 0, 255));

	BFaceArray* faces = new BFaceArray();
	int vi = 0;
	for (int r = 1; r < segments - 1; r++)
	{
		int count0 = pointCount(r);
		int count1 = pointCount(r + 1);
		int head0 = vi;
		int head1 = vi + count0;
		vi += count0;
		if (count0 < count1)
		{
			for (int j = 0; j < 5; j++)
			{
				int i0 = r * j;
				int i1 = (r + 1) * j;
				for (int s = 0; s < r; s++)
				{
					int ia = head0 + i0 + s;
					int ib = head1 + i1 + s;
					int ic = ib + 1;
					int id = ia + 1;
					if (j == 4 && s == (r - 1))
					{
						id = head0;
					}
					faces->append(BFace(ia, ib, ic));
					faces->append(BFace(ia, ic, id));
				}
				int ia = head0 + (i0 + r) % count0;
				int ib = head1 + (i1 + r) % count1;
				int ic = head1 + (i1 + r + 1) % count1;
				faces->append(BFace(ia, ib, ic));
			}
			continue;
		}
		if (count0 > count1)
		{
			for (int j = 0; j < 5; j++)
			{
				int half = segments / 2;
				int level = (half - abs(r + 1 - half));
				int i0 = (level + 1) * j;
				int i1 = level * j;
				for (int s = 0; s < level; s++)
				{
					int ia = head0 + i0 + s;
					int ib = head1 + i1 + s;
					int ic = ib + 1;
					int id = ia + 1;
					if (j == 4 && s == (level - 1))
					{
						ic = head1;
					}
					faces->append(BFace(ia, ib, id));
					faces->append(BFace(ib, ic, id));
				}
				int ia = head0 + (i0 + level) % count0;
				int ib = head1 + (i1 + level) % count1;
				int ic = head0 + (i0 + level + 1) % count0;
				faces->append(BFace(ia, ib, ic));
			}
			continue;
		}
	}
	for (int i = 0; i < 5; i++)
	{
		int ia = vertices->size() - 2;
		int ib = i;
		int ic = (i + 1) % 5;
		faces->append(BFace(ia, ib, ic));
	}
	for (int i = 0; i < 5; i++)
	{
		int ia = vertices->size() - 1;
		int ib = vertices->size() - 7 + (i + 1) % 5;
		int ic = vertices->size() - 7 + i;
		faces->append(BFace(ia, ib, ic));
	}

	boss->setVertices(vertices);
	boss->setNormals(normals);
	boss->setTexCoords(coords);
	boss->setColors(colors);
	boss->setFaces(faces);

	return true;
}

